﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Kang.DbDoc.Domains;
using Kang.DbDoc.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Windows.Input;
using Chloe;
using Kang.DbDoc.Enums;
using Kang.ExtendMethod.Log;
using MahApps.Metro.Controls.Dialogs;
using System.Threading;
using Kang.ExtendMethod;

namespace Kang.DbDoc.ViewModels
{
    public class DatabaseManagerPageViewModel : ObservableRecipient
    {
        private readonly Logger logger = LogManager.GetCurrentClassLogger();
        public string Title => "数据库连接管理";
        public ObservableCollection<DatabaseModel> Databases { get; set; } = new ObservableCollection<DatabaseModel>();
        public ObservableCollection<DatabaseTypeEnum> DatabaseTypes { get; set; } = new ObservableCollection<DatabaseTypeEnum>()
        {
            DatabaseTypeEnum.SqlServer,
            DatabaseTypeEnum.MySql,
            DatabaseTypeEnum.Oracle,
            DatabaseTypeEnum.SQLite,
            DatabaseTypeEnum.PostgreSQL,
        };

        private DatabaseModel _database = null;
        public DatabaseModel Database
        {
            get
            {
                return _database;
            }
            set
            {
                SetProperty(ref _database, value);
            }
        }

        private bool _isBusy = false;
        public bool IsBusy
        {
            get
            {
                return _isBusy;
            }
            set
            {
                SetProperty(ref _isBusy, value);
            }
        }

        private bool _isHostCollapsed = false;
        public bool IsHostCollapsed
        {
            get
            {
                return _isHostCollapsed;
            }
            set
            {
                SetProperty(ref _isHostCollapsed, value);
            }
        }

        private bool _isUsernameCollapsed = false;
        public bool IsUsernameCollapsed
        {
            get
            {
                return _isUsernameCollapsed;
            }
            set
            {
                SetProperty(ref _isUsernameCollapsed, value);
            }
        }

        private bool _isPasswordCollapsed = false;
        public bool IsPasswordCollapsed
        {
            get
            {
                return _isPasswordCollapsed;
            }
            set
            {
                SetProperty(ref _isPasswordCollapsed, value);
            }
        }

        private bool _isSslModeCollapsed = false;
        public bool IsSslModeCollapsed
        {
            get
            {
                return _isSslModeCollapsed;
            }
            set
            {
                SetProperty(ref _isSslModeCollapsed, value);
            }
        }

        public DatabaseManagerPageViewModel()
        {
            try
            {
                using (var my = App.sqlite)
                {
                    my.Query<DbServer>().Where(x => x.IsDelete != true).OrderByDesc(x => x.CreateTime).Select(x => new DatabaseModel(x.DbType)
                    {
                        Id = x.Id,
                        Name = x.Name,
                        DatabaseHost = x.DatabaseHost,
                        DatabasePort = x.DatabasePort ?? 0,
                        DatabaseName = x.DatabaseName,
                        DatabaseUsername = x.DatabaseUsername,
                        DatabasePassword = x.DatabasePassword,
                        TimeOut = x.TimeOut ?? 0,
                        IsSslMode = x.IsSslMode ?? false,
                        ConnectionString = x.ConnectionString,
                        Remark = x.Remark,
                    }).ToListAsync().ContinueWith(x =>
                    {
                        x.Result?.ForEach(a =>
                        {
                            App.Current.Dispatcher.Invoke(() =>
                            {
                                Databases.Add(a);
                            });
                        });
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            Database = Databases.FirstOrDefault();
                        });
                    });
                }
                logger.Debug("服务注册成功：DatabaseManagerPageViewModel");
            }
            catch (Exception e)
            {
                App.ShowMessageAsync("错误", e.Message);
            }
        }

        public ICommand NewDatabase
        {
            get
            {
                return new RelayCommand(() =>
                {
                    var Database = new DatabaseModel(DatabaseTypeEnum.SqlServer)
                    {
                        Name = "新建数据库连接",
                        DatabaseHost = "127.0.0.1",
                        DatabasePort = 1433,
                        DatabaseName = "",
                        DatabaseUsername = "sa",
                        DatabasePassword = "",
                        TimeOut = 60,
                        IsSslMode = false,
                    };
                    Databases.Insert(0, Database);
                    this.Database = Database;
                });
            }
        }

        public ICommand DeleteDatabase
        {
            get
            {
                return new RelayCommand<DatabaseModel>((database) =>
                {
                    if (database == null)
                    {
                        return;
                    }
                    var result = App.ShowMessageAsync("确认", $"确认删除：{database.Name}", MessageDialogStyle.AffirmativeAndNegative);
                    if (result != MessageDialogResult.Affirmative)
                    {
                        return;
                    }
                    IsBusy = true;
                    try
                    {
                        Databases.Remove(database);
                        if (database.Id <= 0)
                        {
                            return;
                        }
                        using (var my = App.sqlite)
                        {
                            my.UpdateAsync<DbServer>(a => a.Id == database.Id, a => new DbServer()
                            {
                                IsDelete = true
                            }).ContinueWith((x) =>
                            {
                                App.Current.Dispatcher.Invoke(() =>
                                {
                                    IsBusy = false;
                                });
                            });
                        }
                        App.ShowMessageAsync("提示", "删除成功！");
                    }
                    catch (Exception e)
                    {
                        App.ShowMessageAsync("错误", e.Message);
                    }
                });
            }
        }

        public ICommand SaveDatabase
        {
            get
            {
                return new RelayCommand<DatabaseModel>((database) =>
                {
                    if (database == null)
                    {
                        return;
                    }
                    try
                    {
                        IsBusy = true;
                        SaveDatabaseToLocalDb(database);
                    }
                    catch (Exception e)
                    {
                        App.ShowMessageAsync("错误", e.Message);
                    }
                    App.ShowMessageAsync("提示", "保存成功！");
                });
            }
        }

        public ICommand DatabaseInfoChanged
        {
            get
            {
                return new RelayCommand(() =>
                {
                    if (Database == null)
                    {
                        return;
                    }
                    Database.RefreshConnectionString();
                });
            }
        }

        public void SaveDatabaseToLocalDb(DatabaseModel database)
        {
            if (database == null)
            {
                return;
            }

            if (database.ConnectionString.IsNotBlank())
            {
                if (database.ConnectionString.StringTrim().LastOrDefault() != ';')
                {
                    database.ConnectionString += ";";
                }
            }
            var now = DateTime.Now;
            using (var my = App.sqlite)
            {
                if (database.Id == 0)
                {
                    my.InsertAsync(new DbServer()
                    {
                        Name = database.Name,
                        DatabaseHost = database.DatabaseHost,
                        DatabasePort = database.DatabasePort,
                        DatabaseName = database.DatabaseName,
                        DatabaseUsername = database.DatabaseUsername,
                        DatabasePassword = database.DatabasePassword,
                        TimeOut = database.TimeOut,
                        IsSslMode = database.IsSslMode,
                        ConnectionString = database.ConnectionString,
                        DbType = database.DatabaseType,
                        Remark = database.Remark,
                        IsDelete = false,
                        CreateTime = now,
                        UpdateTime = now,
                    }).ContinueWith((x) =>
                    {
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            IsBusy = false;
                        });
                        database.Id = x.Result.Id;
                    });
                }
                else
                {
                    my.UpdateAsync<DbServer>(a => a.Id == database.Id, a => new DbServer
                    {
                        Name = database.Name,
                        DatabaseHost = database.DatabaseHost,
                        DatabasePort = database.DatabasePort,
                        DatabaseName = database.DatabaseName,
                        DatabaseUsername = database.DatabaseUsername,
                        DatabasePassword = database.DatabasePassword,
                        TimeOut = database.TimeOut,
                        IsSslMode = database.IsSslMode,
                        ConnectionString = database.ConnectionString,
                        DbType = database.DatabaseType,
                        Remark = database.Remark,
                        UpdateTime = now,
                    }).ContinueWith((x) =>
                    {
                        App.Current.Dispatcher.Invoke(() =>
                        {
                            IsBusy = false;
                        });
                    });
                }
            }
        }
    }
}
